import { ref, onUnmounted } from 'vue'
import { apiDictGetByTypeUsingPost } from '@/api'
import type { ApiDictData, ApiDictType } from '@/api/types'

// 全局字典缓存
const dictCache = new Map<string, {
  data: ApiDictData[]
  timestamp: number
  listeners: Set<Function>
}>()

// 进行中的请求，防止同一 dictType 并发重复请求
const inflightRequests = new Map<string, Promise<ApiDictData[]>>()

// 缓存过期时间（毫秒）
const CACHE_EXPIRE_TIME = 5 * 60 * 1000 // 5分钟

/**
 * 数据字典组合式函数
 * @param dictType 字典类型
 * @returns 字典相关方法和状态
 */
export function useDict(dictType: string) {
  const dictData = ref<ApiDictData[]>([])
  const loading = ref(false)
  const error = ref<string>('')

  // 从缓存获取字典数据
  const getFromCache = (): boolean => {
    const cached = dictCache.get(dictType)
    if (cached) {
      const now = Date.now()
      // 检查缓存是否过期
      if (now - cached.timestamp < CACHE_EXPIRE_TIME) {
        dictData.value = cached.data
        return true
      }
    }
    return false
  }

  // 更新缓存
  const updateCache = (data: ApiDictData[]) => {
    const cached = dictCache.get(dictType)
    if (cached) {
      cached.data = data
      cached.timestamp = Date.now()
      // 通知所有监听器
      cached.listeners.forEach(listener => listener(data))
    } else {
      dictCache.set(dictType, {
        data,
        timestamp: Date.now(),
        listeners: new Set()
      })
    }
  }

  // 注册监听器
  const registerListener = (listener: Function) => {
    let cached = dictCache.get(dictType)
    if (!cached) {
      cached = { data: [], timestamp: 0, listeners: new Set() }
      dictCache.set(dictType, cached)
    }
    cached.listeners.add(listener)
  }

  // 移除监听器
  const removeListener = (listener: Function) => {
    const cached = dictCache.get(dictType)
    if (cached) {
      cached.listeners.delete(listener)
    }
  }

  // 加载字典数据
  const loadDictData = async (forceRefresh = false) => {
    if (!dictType) return
    
    // 如果不需要强制刷新，先尝试从缓存获取
    if (!forceRefresh && getFromCache()) {
      return
    }
    
    // 如果已存在进行中的请求，复用该请求
    const existing = inflightRequests.get(dictType)
    if (existing) {
      loading.value = true
      try {
        const data = await existing
        dictData.value = data
      } finally {
        loading.value = false
      }
      return
    }

    loading.value = true
    error.value = ''

    const requestPromise = (async () => {
      try {
        const response = await apiDictGetByTypeUsingPost({
          params: { dictType }
        })
        if (response) {
          const data = response.dictDataList || []
          updateCache(data)
          return data
        } else {
          error.value = '获取字典数据失败'
          console.error('获取字典数据失败:', response)
          return []
        }
      } catch (err) {
        error.value = '获取字典数据异常'
        console.error('获取字典数据异常:', err)
        return []
      } finally {
        inflightRequests.delete(dictType)
      }
    })()

    inflightRequests.set(dictType, requestPromise)

    try {
      const data = await requestPromise
      dictData.value = data
    } finally {
      loading.value = false
    }
  }

  // 根据字典值获取字典标签
  const getDictLabel = (dictValue: number | string): string => {
    if (dictValue === undefined || dictValue === null) return ''
    const item = dictData.value.find(
      item => item.dictValue?.toString() === dictValue.toString()
    )
    return item?.dictLabel || ''
  }

  // 根据字典标签获取字典值
  const getDictValue = (dictLabel: string): number | string => {
    const item = dictData.value.find(item => item.dictLabel === dictLabel)
    return item?.dictValue || ''
  }

  // 获取字典选项（用于select等组件）
  const getDictOptions = () => {
    return dictData.value.map(item => ({
      label: item.dictLabel || '',
      value: item.dictValue || ''
    }))
  }

  // 检查字典值是否有效
  const isValidDictValue = (dictValue: number | string): boolean => {
    if (dictValue === undefined || dictValue === null) return false
    return dictData.value.some(
      item => item.dictValue?.toString() === dictValue.toString()
    )
  }

  // 清除指定类型的缓存
  const clearCache = () => {
    dictCache.delete(dictType)
  }

  // 清除所有缓存
  const clearAllCache = () => {
    dictCache.clear()
  }

  // 监听字典数据变化的回调
  const dictChangeListener = (newData: ApiDictData[]) => {
    dictData.value = newData
  }

  // 组件卸载时清理监听器
  onUnmounted(() => {
    removeListener(dictChangeListener)
  })

  // 注册监听器
  registerListener(dictChangeListener)

  return {
    dictData,
    loading,
    error,
    loadDictData,
    getDictLabel,
    getDictValue,
    getDictOptions,
    isValidDictValue,
    clearCache,
    clearAllCache,
    // 刷新数据（强制重新加载）
    refresh: () => loadDictData(true)
  }
}

// 批量加载多个字典
export function useDicts(dictTypes: string[]) {
  const dictMap = ref<Record<string, ApiDictData[]>>({})
  const loading = ref(false)
  const error = ref<string>('')

  const loadAllDicts = async () => {
    if (!dictTypes || dictTypes.length === 0) return
    
    loading.value = true
    error.value = ''
    
    try {
      const promises = dictTypes.map(type => 
        apiDictGetByTypeUsingPost({ params: { dictType: type } })
      )
      
      const results = await Promise.all(promises)
      
      results.forEach((result, index) => {
        const type = dictTypes[index]
        if (result.code === 0 && result.data) {
          dictMap.value[type] = result.data.dictDataList || []
        } else {
          console.error(`获取字典[${type}]数据失败:`, result)
        }
      })
    } catch (err) {
      error.value = '批量获取字典数据异常'
      console.error('批量获取字典数据异常:', err)
    } finally {
      loading.value = false
    }
  }

  const getDictByType = (type: string) => {
    return dictMap.value[type] || []
  }

  const getDictLabel = (type: string, value: number | string) => {
    const dictData = getDictByType(type)
    const item = dictData.find(
      item => item.dictValue?.toString() === value.toString()
    )
    return item?.dictLabel || ''
  }

  return {
    dictMap,
    loading,
    error,
    loadAllDicts,
    getDictByType,
    getDictLabel
  }
}